#ifndef OBR_SHADER_TRIGONOMETRICFUNCTION_CUH
#define OBR_SHADER_TRIGONOMETRICFUNCTION_CUH

static __forceinline__ __device__ float cos(float3 v1, float3 v2)
{
    return dot(v1, v2);
}

static __forceinline__ __device__ float cos2(float3 v1, float3 v2)
{
    return dot(v1, v2) * dot(v1, v2);
}

static __forceinline__ __device__ float sin2(float3 v1, float3 v2)
{
    return clamp(1.0 - cos2(v1, v2), 0.0f, 1.0f);
}

static __forceinline__ __device__ float sin(float3 v1, float3 v2)
{
    return sqrtf(sin2(v1, v2));
}

static __forceinline__ __device__ float tan(float3 v1, float3 v2)
{
    return sin(v1, v2) / cos(v1, v2);
}

static __forceinline__ __device__ float tan2(float3 v1, float3 v2)
{
    return sin2(v1, v2) / cos2(v1, v2);
}

static __forceinline__ __device__ float local_cos_phi(float3 &w)
{
    float3 n = make_float3(0.0, 0.0, 1.0);
    float sin_theta = sin(w, n);
    return (sin_theta == 0) ? 1 : clamp(w.x / sin_theta, -1.0f, 1.0f);
}

static __forceinline__ __device__ float local_sin_phi(float3 &w)
{
    float3 n = make_float3(0.0, 0.0, 1.0);
    float sin_theta = sin(w, n);
    return (sin_theta == 0) ? 0 : clamp(w.y / sin_theta, -1.0f, 1.0f);
}

#endif